//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <ddk.h>
#include <PowerManager.h>

static PowerManager powerManager;

EXTERN_C void PCFOnkey1sOffEnable(BOOL IsEnable);

ECode PowerManager::Read(
        /* [in] */ UINT64 u64Offset,
       /* [in] */ UINT uNumberOfBytesToRead,
        /* [out] */ EzByteBuf ebbData,
        /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode PowerManager::Write(
        /* [in] */ UINT64 u64Offset,
        /* [in] */ EzByteBuf ebbData,
        /* [out] */ UINT * puNumberOfBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode PowerManager::Control(
        /* [in] */ INT nControlCode,
        /* [in] */ EzByteBuf ebbInData,
        /* [out] */ EzByteBuf * pOutData,
        /* [out] */ IEvent * * ppCompletionEvent)
{
    switch(nControlCode)
    {
        //0-49,for ntos compliance
//        case 0:
//        {//means SetMode
//            ULONG * t=(ULONG*)(char*)ebbInData;
//            int * task_id=(int*)t;
//            ULONG *mode=++t;
//            if(Power_SetCpuMode(*task_id,*mode)<0)
//            {
//                 goto Exit;
//            }
//            break;
//        }
//        case 1:
//        {//means SetPolicy
//            ULONG * t=(ULONG*)(char*)ebbInData;
//            int * task_id=(int*)t;
//            ULONG *policy_type=++t;
//            if(Power_SetPolicy(*task_id,*policy_type)<0)
//            {
//                goto Exit;
//            }
//            break;
//        }
//        case 2:
//        {//means InitDevPowerMode
//            ULONG * t=(ULONG*)(char*)ebbInData;
//            int task_id=(int)t[0];
//            CVirtualDevice *pvd=(CVirtualDevice *)t[1];
//            ULONG DevMode=t[2];
//            UpdateTaskDevMode(task_id,pvd,DevMode);
//            break;
//        }
//        case 3:
//        {//means KeepSpecifiedDevMode
//            ULONG * t=(ULONG*)(char*)ebbInData;
//            int task_id=(int)t[0];
//            CVirtualDevice *pvd=(CVirtualDevice *)t[1];
//            ULONG DevMode=t[2];
//            BOOL KeepMode=(BOOL)t[3];
//            UpdateTaskKeepMode(task_id,pvd,DevMode,KeepMode);
//            break;
//        }
//        case 4:
//        {//means SetChangeModeInterval
//            ULONG * t=(ULONG*)(char*)ebbInData;
//            int task_id=(int)t[0];
//            CVirtualDevice *pvd=(CVirtualDevice *)t[1];
//            ULONG Interval=t[2];
//            UpdateTaskChangeInterval(task_id,pvd,Interval);
//            break;
//        }
//        case 10:
//        {//means GetMode
//            ULONG mode=Power_GetCpuMode();
//            assert(pOutData->Capacity () >= (int)sizeof(ULONG));
//            pOutData->Copy(&mode, (int)sizeof(ULONG));
//            break;
//        }
//        case 11:
//        {//means GetPolicy
//            ULONG policy=Power_GetPolicy();
//            assert(pOutData->Capacity () >= (int)sizeof(ULONG));
//            pOutData->Copy(&policy, (int)sizeof(ULONG));
//            break;
//        }

        //50-99,for test
        case 50:
            ShowDeviceStatus();
            break;

        //100-999,for power manager api
        case 100: {/*SetLCDPolicy*/
            int nInterval=*(int *)(char *)ebbInData;
            switch(nInterval) {
                case -1:PoSetLcdPowerOn(TRUE);break;
                case 0:PoSetLcdPowerOn(FALSE);break;
                default: {
                    PoSetLcdPowerOn(FALSE);
                    PoSetLcdPoweroffInterval(nInterval);
                    break;
                }
            }
            break;
        }
        case 102: {/*GetLcdPowerPolicy 0:normal 1:always on*/
            assert(NULL != (char *)ebbOutData);
            unsigned long uPolicy = PoGetLcdPowerPolicy();
            pOutData->Copy(&uPolicy, sizeof(unsigned long));
            break;
        }
        case 103: {/*PoLockScreen*/
            BOOL bLock = *(bool *)(char *)ebbInData;
            PoSetCpuPowerOn(!bLock);
            break;
        }
        case 104: {/*PoGetBootStatus*/
            break;
        }
        case 105: {/*PoReboot*/
            break;
        }
        case 106: {/*PoShutdown*/
            break;
        }
        case 205: {/*Disable Onkey1S Shutdown*/
            break;
        }
        case 206: {/*Enable Onkey1S Shutdown*/
            break;
        }

        default:
            break;
    }
    return NOERROR;
}

void pm_do_idle();
void CpuIdleWakeupCallback(int eType, int nCode, void *pParam);
static int count=0;
void EnterIdleModeCallback(int eType, int nCode, void *pParam)
{
    pm_do_idle();
    return ;
}

/////////////////////////////////////////////////////////////////////
EXTERN IDeviceDriver * CDECL CreatePowerManagers(uint_t uDeviceNo, void *pvParameter)
{
    PowerManager * pPowerManager = &powerManager;
    AddNotify(EVENT_IDLE,(void *)EnterIdleModeCallback);//for os idle thread use
    NotifyByIsr(EVENT_INPUT, 0, NULL);//simulate an input to enable keypad and lcd power management
    if(pPowerManager)kprintf("add power manager ok\n");
    return (IDeviceDriver *)pPowerManager;
}
